package sfeir.gwt.ergosoom.server.service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import sfeir.gwt.ergosoom.client.model.Person;
import sfeir.gwt.ergosoom.client.model.Profile;

import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;

public class ProfileAccess {

    public void save(Profile p) {
        DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
//            Entity entity = null;
//            // TODO check key/alias association
//            if (0 == p.getKey())
//                entity = new Entity("Profile");
//            else
//                entity = ds.get(KeyFactory.createKey("Profile", p.getKey()));
            Entity entity = ds.prepare(new Query("Profile").addFilter("email", FilterOperator.EQUAL, p.getEmail())).asSingleEntity();
            if (null == entity)
                entity = new Entity("Profile");
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(p.getPerson());
            byte[] person = bos.toByteArray();
            entity.setProperty("alias", p.getAlias());
            entity.setProperty("email", p.getEmail());
            String pass = p.getPassword();
            if (pass != null && !pass.isEmpty())
                entity.setProperty("passwd", pass);
            entity.setProperty("person", new Blob(person));
            ds.put(entity);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public Profile get(String id) {
        DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
        Entity entity = ds.prepare(new Query("Profile").addFilter("alias", FilterOperator.EQUAL, id)).asSingleEntity();
        if (entity == null)
            entity = ds.prepare(new Query("Profile").addFilter("email", FilterOperator.EQUAL, id)).asSingleEntity();
        if (entity != null) {
            Blob pbytes = (Blob) entity.getProperty("person");
            ObjectInputStream ois = null;
            String email = (String) entity.getProperty("email");
            Person p = null;
            try {
                ois = new ObjectInputStream(new ByteArrayInputStream(pbytes.getBytes()));
                p = (Person) ois.readObject();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } finally {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            Profile profile = new Profile(p, id);
            profile.setPassword((String) entity.getProperty("passwd"));
            profile.setEmail(email);
            profile.setAlias((String) entity.getProperty("alias"));
            return profile;
        }
        return null;
    }

    public String getPassword(String alias) {
        DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
        Entity entity = ds.prepare(new Query("Profile").addFilter("alias", FilterOperator.EQUAL, alias)).asSingleEntity();
        if (entity == null)
            entity = ds.prepare(new Query("Profile").addFilter("email", FilterOperator.EQUAL, alias)).asSingleEntity();
        if (entity != null) {
            String password = (String) entity.getProperty("passwd");
            return password;
        }
        return null;
    }
}
